package com.sailing.xjpb.ipaas.client.translate.handler;

import com.sailing.xjpb.common.SailingReflectionUtils;
import com.sailing.xjpb.common.web.translate.TranslateHandler;
import com.sailing.xjpb.ipaas.client.core.Sip3Service;
import com.sailing.xjpb.ipaas.client.entity.bo.SipOrganizationBO;
import com.sailing.xjpb.ipaas.client.translate.annotation.IpaasOrgField;
import com.sailing.xjpb.ipaas.client.translate.annotation.SourceFieldType;
import com.sailing.xjpb.ipaas.client.translate.enumer.IpaasOrgFieldName;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.lang.reflect.Field;
import java.util.*;

/**
 * Ipaas组织信息翻译处理器：处理VO标注有@IpaasOrgField注解的字段翻译
 *
 * @author YaoWei
 * createDate: 2020/11/26
 */
@Slf4j
public class IpaasOrgTranslateHandler implements TranslateHandler {

    @Autowired
    private Sip3Service sip3Service;

    @Override
    public void doTranslate(Class<?> itemClass, List<Field> translateFields, Collection<?> datas) {
        Map<String, SipOrganizationBO> cacheUnit = new HashMap<>(datas.size());
        try {
            for (Field field : translateFields) {
                IpaasOrgField ipaasOrgField = field.getAnnotation(IpaasOrgField.class);
                String sourceFieldName = ipaasOrgField.sourceField();
                Field sourceField = SailingReflectionUtils.findAndMakeAccessible(itemClass, sourceFieldName);
                IpaasOrgFieldName orgFieldName = ipaasOrgField.fieldName();
                SourceFieldType sourceFieldType = ipaasOrgField.sourceFieldType();
                for (Object sourceData : datas) {
                    Object sourceFieldValue = SailingReflectionUtils.getField(sourceField, sourceData);
                    String sourceFieldValueStr = Objects.toString(sourceFieldValue, null);
                    String translateValue = this.getTranslateValue(sourceFieldValueStr, orgFieldName, sourceFieldType
                            , cacheUnit);
                    SailingReflectionUtils.setField(field, sourceData, translateValue);
                }
            }
        } catch (Exception ex) {
            log.error("doTranslate-ipaas组织信息翻译失败：{}", ex.getMessage());
        }
    }

    @Override
    public SailingReflectionUtils.FieldFilter getTranslateFieldFilter() {
        return field -> field.getAnnotation(IpaasOrgField.class) != null;
    }

    @Override
    public int getOrder() {
        return 5;
    }

    /**
     * 获取翻译后的值（如果翻译失败或者获取不到值，返回翻译前的值）
     *
     * @param sourceFieldValue 翻译之前的值
     * @param orgFieldName     需要根据组织信息的哪个字段进行翻译
     * @param sourceFieldType  指定源字段是组织机构ID还是组织机构code
     * @param cacheUnit        临时缓存
     */
    private String getTranslateValue(String sourceFieldValue, IpaasOrgFieldName orgFieldName,
                                     SourceFieldType sourceFieldType, Map<String,
            SipOrganizationBO> cacheUnit) {
        if (StringUtils.isBlank(sourceFieldValue)) {
            return sourceFieldValue;
        }
        SipOrganizationBO translateSource = cacheUnit.get(sourceFieldValue);
        if (translateSource == null) {
            if (sourceFieldType == SourceFieldType.ORG_CODE) {
                translateSource = sip3Service.querySipOrganizationByOrgCode(sourceFieldValue);
            } else {
                translateSource = sip3Service.querySipOrganizationByOrgId(sourceFieldValue);
            }
            cacheUnit.put(sourceFieldValue, translateSource);
        }
        if (translateSource == null) {
            return sourceFieldValue;
        }
        return getTranslateValue(sourceFieldValue, orgFieldName, translateSource);
    }

    /**
     * 获取翻译后的用户字段值
     *
     * @param sourceFieldValue 用户ID
     * @param orgFieldName     需要翻译的字段
     * @param translateSource  用户信息
     * @return 翻译后的值
     */
    private String getTranslateValue(String sourceFieldValue, IpaasOrgFieldName orgFieldName,
                                     SipOrganizationBO translateSource) {
        String translateValue;
        if (orgFieldName == IpaasOrgFieldName.ORG_NAME) {
            translateValue = translateSource.getOrgName();
        } else {
            translateValue = sourceFieldValue;
        }
        return translateValue;
    }

}
